import os
import win32com.client
from python_project.read_file import find_pst_folder,enumerate_folders
from python_project.utils import make_name
import subprocess
import time
import schedule
import logging

from collections import deque
from queue import Queue
import threading

# 要遍历的文件
pst_queue = Queue()
# 并发线程数
DOWNLOADER_NUM = 10 
# 线程池
thread_pool = []
class Exchange_ex():
    """
    exchange数据抽取主程序类，还是一如既往的封装成类。

    """
    
    def __init__(self):
        self.Outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")


    def walkFile(self,file:str,lis):

        for root, dirs, files in os.walk(file):

            # root 表示当前正在访问的文件夹路径
            # dirs 表示该文件夹下的子目录名list
            # files 表示该文件夹下的文件list

            # 遍历文件
            for f in files:
                temp = os.path.join(root, f)
                if temp.endswith(".pst"):
                    lis.append(os.path.join(root, f))
            # 遍历所有的文件夹
            for d in dirs:
                print(os.path.join(root, d))
        return lis



    def start_anlyze(self,pst_queue):
        """
        开始分析遍历文件夹下的所有pst文件
        :return:
        """
        # self.lis = self.walkFile(self.path,self.lis)  
        self.pst_queue = pst_queue
        # TODO：启用队列代替list,多个线程从队列中取path,每个线程调用self.run方法（target指定run）
        # TODO：#不停地从pst队列中取Pst_path，如果Pst_path不是None，遍历pst目录。
        while not self.pst_queue.empty():
            Pst_path = self.pst_queue.pop()
            if Pst_path is not None:
                try:
                    #这里遍历每个人的邮箱，一个人错了，跳过，做好日志记录，不要影响下个人的使用。
                    print(Pst_path)
                    name = make_name(Pst_path)

                    self.run(Pst_path,name)
                    time.sleep(1)
                except Exception as e:
                    logging.error("{0}:who{1}".format(e,Pst_path))


    def run(self,pst_path:str,name):
        self.Outlook.AddStore(pst_path)
        PSTFolderObj = find_pst_folder(self.Outlook, pst_path)
        try:
            enumerate_folders(PSTFolderObj,name)

            self.Outlook.RemoveStore(PSTFolderObj)
        except Exception as exc:
            self.Outlook.RemoveStore(PSTFolderObj)
            print(exc)


def start():
    """
    入口程序
    :return:
    """

    text1 = "$temp = Get-Mailbox -Server EXCHANGE2016"

    text2 = "$temp = Get-Mailbox -Server EXCHANGE2016;\
            foreach($u in $temp){ \
                    New-MailboxExportRequest -Mailbox $u.SamAccountName -FilePath \"\\\\EXCHANGE2016\\readpst\\$u.pst\" -Priority high -RequestExpiryInterval 00.00:01:00}"

    run = "powershell -psc \"C:\\Program Files\Microsoft\Exchange Server\V15\\Bin\exshell.psc1\" %s" % text2

    # aa='dir'
    s = subprocess.Popen(run, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
    # print(s.returncode)
    # print(s.wait())
    print(s.stdout.readlines())


    time.sleep(10) # 5秒之后开始运行

    event = Exchange_ex()

    pst_lis = event.walkFile('D:\\readpst',[])
    pirnt(pst_lis) # 这里看下pst_lis的输出是不是空
    # TODO：利用deque模块将列表换做队列使用，利用队列配合线程实现多线程
    pst_queue = deque(pst_lis)
    # TODO：启动多个子线程
    for i in range(DOWNLOADER_NUM):
        # TODO：创建一个线程对象 target 指向 event.start_anlyze() 函数,启动线程
        t = threading.Thread(target=event.start_anlyze(pst_queue))
        t.start()
        thread_pool.append(t)

    # 阻塞队列，直到队列中没有任何url
    # urls_queue.join()

    # TODO：阻塞线程，直到所有线程结束
    for t in thread_pool:
        t.join()
    
    


if __name__ == "__main__":

    logger = logging.getLogger()
    logger.setLevel(logging.INFO)  # Log等级总开关
    # 第二步，创建一个handler，用于写入日志文件
    rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))

    logfile = "logs/" + rq + '.log'

    fh = logging.FileHandler(logfile, mode='w')
    fh.setLevel(logging.DEBUG)  # 输出到file的log等级的开关
    # 第三步，定义handler的输出格式
    formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
    fh.setFormatter(formatter)
    # 第四步，将logger添加到handler里面
    logger.addHandler(fh)
    # 日志



    # schedule.every(3).minutes.do(start)  # 每隔十分钟执行一次任务
    # schedule.every().hour.do(job, name)  # 每隔一小时执行一次任务
    # schedule.every().day.at("10:47").do(start)  # 每天的10:30执行一次任务
    # schedule.every(5).to(10).days.do(job, name)  # 每隔5到10天执行一次任务
    # schedule.every().monday.do(job, name)  # 每周一的这个时候执行一次任务
    # schedule.every().wednesday.at("13:15").do(job, name)  # 每周三13:15执行一次任务
    # start()

    while True:
        try:
            logging.info("开始工作")
            schedule.run_pending()  # run_pending：运行所有可以运行的任务
            time.sleep(5)
        except Exception as e:
            logging.error(e)
            print(e)




